package com.star.rpc.server;


import com.star.rpc.RpcApplication;
import com.star.rpc.modal.RpcRequest;
import com.star.rpc.modal.RpcResponse;
import com.star.rpc.registry.LocalRegistry;
import com.star.rpc.serializer.JdkSerializer;
import com.star.rpc.serializer.Serializer;

import com.star.rpc.spi.SerializerFactory;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * packageName com.star.starrpc.server
 *
 * @author zerostart
 * @className HttpServerHandler
 * @date 2024/11/17
 * @description HTTP请求
 */
@Slf4j
public class HttpServerHandler implements Handler<HttpServerRequest> {


    @Override
    public void handle(HttpServerRequest request) {
        // 指定序列化器
//        final Serializer serializer = new JdkSerializer();
        // 指定序列化器

        final Serializer serializer = SerializerFactory.getInstance(RpcApplication.getRpcConfig().getSerializer());

        log.info("receive serializer: {}", serializer);
        //记录日志
        System.out.println("receive request: " + request.method() + " " + request.uri());

        // 异步处理请求
        request.bodyHandler(body -> {
            byte[] bytes = body.getBytes();

            RpcRequest rpcRequest = null;

            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 构造响应结果对象
            RpcResponse rpcResponse = new RpcResponse();

            // 如果请求结果为null, 处理请求
            if (rpcRequest == null) {
                rpcResponse.setMessage("request is null");
                doResponse(request, rpcResponse, serializer);
                return;
            }

            // 向服务提供者发起调用
            try {
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());

                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());

                // 封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");

            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }

            doResponse(request, rpcResponse, serializer);

        });
    }

    /**
     * 响应
     * @param request
     * @param rpcResponse
     * @param serializer
     */
    private void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse response = request.response()
                .putHeader("content-type", "application/json");

        try {
            byte[] serialized = serializer.serialize(rpcResponse);
            response.end(Buffer.buffer(serialized));
        } catch (Exception e) {
            e.printStackTrace();
            response.end(Buffer.buffer());
        }
    }
}
